package cn.yanceysong.gitstats.report;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import cn.yanceysong.gitstats.model.*;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 报告生成器
 */
@Slf4j
public class ReportGenerator {
    
    /**
     * 生成JSON格式报告
     */
    public String generateJsonReport(GitStatsResult result) {
        try {
            return JSON.toJSONString(result, JSONWriter.Feature.PrettyFormat);
        } catch (Exception e) {
            log.error("生成JSON报告失败", e);
            return "{\"error\": \"生成JSON报告失败: " + e.getMessage() + "\"}";
        }
    }
    
    /**
     * 生成CSV格式报告
     */
    public String generateCsvReport(GitStatsResult result) {
        StringBuilder csv = new StringBuilder();
        
        // 总体统计
        csv.append("=== 总体统计 ===\n");
        csv.append("仓库路径,").append(result.getRepositoryPath()).append("\n");
        csv.append("总提交数,").append(result.getTotalCommits()).append("\n");
        csv.append("总贡献者数,").append(result.getTotalContributors()).append("\n");
        csv.append("总代码行数,").append(result.getTotalLines()).append("\n");
        csv.append("总新增行数,").append(result.getTotalAddedLines()).append("\n");
        csv.append("总删除行数,").append(result.getTotalDeletedLines()).append("\n");
        csv.append("总修改行数,").append(result.getTotalModifiedLines()).append("\n");
        csv.append("统计开始时间,").append(result.getStartTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n");
        csv.append("统计结束时间,").append(result.getEndTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        // 贡献者统计
        csv.append("=== 贡献者统计 ===\n");
        csv.append("姓名,邮箱,提交数,总行数,新增行数,删除行数,修改行数,首次提交时间,最后提交时间\n");
        
        List<ContributorStats> contributors = result.getContributors();
        contributors.sort((a, b) -> Integer.compare(b.getCommitCount(), a.getCommitCount()));
        
        for (ContributorStats contributor : contributors) {
            csv.append(escapeCsv(contributor.getName())).append(",");
            csv.append(escapeCsv(contributor.getEmail())).append(",");
            csv.append(contributor.getCommitCount()).append(",");
            csv.append(contributor.getTotalLines()).append(",");
            csv.append(contributor.getAddedLines()).append(",");
            csv.append(contributor.getDeletedLines()).append(",");
            csv.append(contributor.getModifiedLines()).append(",");
            csv.append(contributor.getFirstCommitTime() != null ? 
                contributor.getFirstCommitTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : "").append(",");
            csv.append(contributor.getLastCommitTime() != null ? 
                contributor.getLastCommitTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : "").append("\n");
        }
        
        return csv.toString();
    }
    
    /**
     * 生成HTML格式报告
     */
    public String generateHtmlReport(GitStatsResult result) {
        StringBuilder html = new StringBuilder();

        html.append("<!DOCTYPE html>\n");
        html.append("<html>\n");
        html.append("<head>\n");
        html.append("    <meta charset=\"UTF-8\">\n");
        html.append("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");
        html.append("    <title>Git仓库统计报告</title>\n");
        html.append("    <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n");
        html.append("    <style>\n");
        html.append(getEnhancedCss());
        html.append("    </style>\n");
        html.append("</head>\n");
        html.append("<body>\n");

        html.append("    <div class=\"container\">\n");

        // 标题部分
        html.append("        <div class=\"header\">\n");
        html.append("            <h1>Git仓库统计报告</h1>\n");
        html.append("            <p>").append(escapeHtml(result.getRepositoryPath())).append("</p>\n");
        html.append("            <p>统计时间: ").append(result.getStartTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
             .append(" - ").append(result.getEndTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("</p>\n");
        html.append("        </div>\n");

        // 统计卡片
        html.append("        <div class=\"stats-grid\">\n");
        html.append("            <div class=\"stat-card\">\n");
        html.append("                <h3>总提交数</h3>\n");
        html.append("                <div class=\"number\">").append(result.getTotalCommits()).append("</div>\n");
        html.append("            </div>\n");
        html.append("            <div class=\"stat-card\">\n");
        html.append("                <h3>贡献者数</h3>\n");
        html.append("                <div class=\"number\">").append(result.getTotalContributors()).append("</div>\n");
        html.append("            </div>\n");
        html.append("            <div class=\"stat-card\">\n");
        html.append("                <h3>新增行数</h3>\n");
        html.append("                <div class=\"number\">").append(result.getTotalAddedLines()).append("</div>\n");
        html.append("            </div>\n");
        html.append("            <div class=\"stat-card\">\n");
        html.append("                <h3>删除行数</h3>\n");
        html.append("                <div class=\"number\">").append(result.getTotalDeletedLines()).append("</div>\n");
        html.append("            </div>\n");
        html.append("        </div>\n");

        // 图表部分
        html.append("        <div class=\"charts-section\">\n");
        html.append("            <h2>数据可视化</h2>\n");
        html.append("            <div class=\"charts-grid\">\n");
        html.append("                <div class=\"chart-container\">\n");
        html.append("                    <canvas id=\"contributorChart\"></canvas>\n");
        html.append("                </div>\n");
        html.append("                <div class=\"chart-container\">\n");
        html.append("                    <canvas id=\"linesChart\"></canvas>\n");
        html.append("                </div>\n");
        html.append("            </div>\n");
        html.append("        </div>\n");

        // 贡献者统计表格
        html.append("        <div class=\"table-section\">\n");
        html.append("            <h2>贡献者详细统计</h2>\n");
        html.append("            <table>\n");
        html.append("                <tr>\n");
        html.append("                    <th>排名</th>\n");
        html.append("                    <th>姓名</th>\n");
        html.append("                    <th>邮箱</th>\n");
        html.append("                    <th>提交数</th>\n");
        html.append("                    <th>贡献度</th>\n");
        html.append("                    <th>新增行数</th>\n");
        html.append("                    <th>删除行数</th>\n");
        html.append("                    <th>修改行数</th>\n");
        html.append("                    <th>首次提交</th>\n");
        html.append("                    <th>最后提交</th>\n");
        html.append("                </tr>\n");

        List<ContributorStats> contributors = result.getContributors();
        contributors.sort((a, b) -> Integer.compare(b.getCommitCount(), a.getCommitCount()));

        int maxCommits = contributors.isEmpty() ? 1 : contributors.get(0).getCommitCount();

        for (int i = 0; i < contributors.size(); i++) {
            ContributorStats contributor = contributors.get(i);
            double percentage = (double) contributor.getCommitCount() / maxCommits * 100;

            html.append("                <tr>\n");
            html.append("                    <td><span class=\"contributor-rank\">").append(i + 1).append("</span></td>\n");
            html.append("                    <td>").append(escapeHtml(contributor.getName())).append("</td>\n");
            html.append("                    <td>").append(escapeHtml(contributor.getEmail())).append("</td>\n");
            html.append("                    <td>").append(contributor.getCommitCount()).append("</td>\n");
            html.append("                    <td>\n");
            html.append("                        <div class=\"progress-bar\">\n");
            html.append("                            <div class=\"progress-fill\" style=\"width: ").append(String.format("%.1f", percentage)).append("%\"></div>\n");
            html.append("                        </div>\n");
            html.append("                        ").append(String.format("%.1f", percentage)).append("%\n");
            html.append("                    </td>\n");
            html.append("                    <td>").append(contributor.getAddedLines()).append("</td>\n");
            html.append("                    <td>").append(contributor.getDeletedLines()).append("</td>\n");
            html.append("                    <td>").append(contributor.getModifiedLines()).append("</td>\n");
            html.append("                    <td>").append(contributor.getFirstCommitTime() != null ?
                contributor.getFirstCommitTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) : "").append("</td>\n");
            html.append("                    <td>").append(contributor.getLastCommitTime() != null ?
                contributor.getLastCommitTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) : "").append("</td>\n");
            html.append("                </tr>\n");
        }

        html.append("            </table>\n");
        html.append("        </div>\n");
        html.append("    </div>\n");

        // 添加 JavaScript 图表代码
        html.append(generateChartScript(result));

        html.append("</body>\n");
        html.append("</html>\n");
        
        return html.toString();
    }

    /**
     * 获取增强的CSS样式
     */
    private String getEnhancedCss() {
        return """
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f5f5;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 2rem;
            border-radius: 10px;
            margin-bottom: 2rem;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5rem;
            margin-bottom: 0.5rem;
        }

        .header p {
            font-size: 1.1rem;
            opacity: 0.9;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
            margin-bottom: 2rem;
        }

        .stat-card {
            background: white;
            padding: 1.5rem;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            text-align: center;
            transition: transform 0.3s ease;
        }

        .stat-card:hover {
            transform: translateY(-5px);
        }

        .stat-card h3 {
            color: #667eea;
            font-size: 0.9rem;
            text-transform: uppercase;
            letter-spacing: 1px;
            margin-bottom: 0.5rem;
        }

        .stat-card .number {
            font-size: 2rem;
            font-weight: bold;
            color: #333;
        }

        .charts-section {
            background: white;
            padding: 2rem;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 2rem;
        }

        .charts-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 2rem;
            margin-top: 1rem;
        }

        .chart-container {
            position: relative;
            height: 300px;
        }

        .table-section {
            background: white;
            padding: 2rem;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .table-section h2 {
            color: #333;
            margin-bottom: 1rem;
            font-size: 1.5rem;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 1rem;
        }

        th, td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }

        th {
            background-color: #f8f9fa;
            font-weight: 600;
            color: #555;
            position: sticky;
            top: 0;
        }

        tr:hover {
            background-color: #f8f9fa;
        }

        .contributor-rank {
            display: inline-block;
            background: #667eea;
            color: white;
            padding: 4px 8px;
            border-radius: 15px;
            font-size: 0.8rem;
            font-weight: bold;
        }

        .progress-bar {
            background-color: #e9ecef;
            border-radius: 10px;
            height: 8px;
            overflow: hidden;
            margin-top: 4px;
        }

        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #667eea, #764ba2);
            border-radius: 10px;
            transition: width 0.3s ease;
        }

        @media (max-width: 768px) {
            .charts-grid {
                grid-template-columns: 1fr;
            }

            .stats-grid {
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            }

            .header h1 {
                font-size: 2rem;
            }

            table {
                font-size: 0.9rem;
            }
        }
        """;
    }

    /**
     * 生成图表的JavaScript代码
     */
    private String generateChartScript(GitStatsResult result) {
        StringBuilder script = new StringBuilder();

        script.append("    <script>\n");
        script.append("        document.addEventListener('DOMContentLoaded', function() {\n");

        // 贡献者提交数图表数据
        List<ContributorStats> contributors = result.getContributors();
        contributors.sort((a, b) -> Integer.compare(b.getCommitCount(), a.getCommitCount()));

        // 只显示前10个贡献者
        List<ContributorStats> topContributors = contributors.subList(0, Math.min(10, contributors.size()));

        script.append("            // 贡献者提交数图表\n");
        script.append("            const contributorCtx = document.getElementById('contributorChart').getContext('2d');\n");
        script.append("            new Chart(contributorCtx, {\n");
        script.append("                type: 'bar',\n");
        script.append("                data: {\n");
        script.append("                    labels: [");

        for (int i = 0; i < topContributors.size(); i++) {
            if (i > 0) script.append(", ");
            script.append("'").append(escapeJs(topContributors.get(i).getName())).append("'");
        }

        script.append("],\n");
        script.append("                    datasets: [{\n");
        script.append("                        label: '提交数',\n");
        script.append("                        data: [");

        for (int i = 0; i < topContributors.size(); i++) {
            if (i > 0) script.append(", ");
            script.append(topContributors.get(i).getCommitCount());
        }

        script.append("],\n");
        script.append("                        backgroundColor: 'rgba(102, 126, 234, 0.8)',\n");
        script.append("                        borderColor: 'rgba(102, 126, 234, 1)',\n");
        script.append("                        borderWidth: 1\n");
        script.append("                    }]\n");
        script.append("                },\n");
        script.append("                options: {\n");
        script.append("                    responsive: true,\n");
        script.append("                    maintainAspectRatio: false,\n");
        script.append("                    plugins: {\n");
        script.append("                        title: {\n");
        script.append("                            display: true,\n");
        script.append("                            text: '贡献者提交数排行'\n");
        script.append("                        }\n");
        script.append("                    },\n");
        script.append("                    scales: {\n");
        script.append("                        y: {\n");
        script.append("                            beginAtZero: true\n");
        script.append("                        }\n");
        script.append("                    }\n");
        script.append("                }\n");
        script.append("            });\n\n");

        // 代码行数分布图表
        script.append("            // 代码行数分布图表\n");
        script.append("            const linesCtx = document.getElementById('linesChart').getContext('2d');\n");
        script.append("            new Chart(linesCtx, {\n");
        script.append("                type: 'doughnut',\n");
        script.append("                data: {\n");
        script.append("                    labels: ['新增行数', '删除行数', '修改行数'],\n");
        script.append("                    datasets: [{\n");
        script.append("                        data: [")
            .append(result.getTotalAddedLines()).append(", ")
            .append(result.getTotalDeletedLines()).append(", ")
            .append(result.getTotalModifiedLines()).append("],\n");
        script.append("                        backgroundColor: [\n");
        script.append("                            'rgba(40, 167, 69, 0.8)',\n");
        script.append("                            'rgba(220, 53, 69, 0.8)',\n");
        script.append("                            'rgba(255, 193, 7, 0.8)'\n");
        script.append("                        ],\n");
        script.append("                        borderColor: [\n");
        script.append("                            'rgba(40, 167, 69, 1)',\n");
        script.append("                            'rgba(220, 53, 69, 1)',\n");
        script.append("                            'rgba(255, 193, 7, 1)'\n");
        script.append("                        ],\n");
        script.append("                        borderWidth: 2\n");
        script.append("                    }]\n");
        script.append("                },\n");
        script.append("                options: {\n");
        script.append("                    responsive: true,\n");
        script.append("                    maintainAspectRatio: false,\n");
        script.append("                    plugins: {\n");
        script.append("                        title: {\n");
        script.append("                            display: true,\n");
        script.append("                            text: '代码行数分布'\n");
        script.append("                        }\n");
        script.append("                    }\n");
        script.append("                }\n");
        script.append("            });\n");
        script.append("        });\n");
        script.append("    </script>\n");

        return script.toString();
    }

    /**
     * 转义JavaScript字符串
     */
    private String escapeJs(String text) {
        if (text == null) return "";
        return text.replace("\\", "\\\\")
                  .replace("'", "\\'")
                  .replace("\"", "\\\"")
                  .replace("\n", "\\n")
                  .replace("\r", "\\r");
    }

    /**
     * 保存报告到文件
     */
    public void saveReportToFile(String content, String filePath, String format) throws IOException {
        File file = new File(filePath);
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(content);
        }
        log.info("{}报告已保存到: {}", format.toUpperCase(), file.getAbsolutePath());
    }
    
    /**
     * 生成并保存所有格式的报告
     */
    public void generateAllReports(GitStatsResult result, String outputDir) throws IOException {
        File dir = new File(outputDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        
        String timestamp = result.getStartTime().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String baseName = "git-stats-" + timestamp;
        
        // JSON报告
        String jsonReport = generateJsonReport(result);
        saveReportToFile(jsonReport, new File(dir, baseName + ".json").getAbsolutePath(), "JSON");
        
        // CSV报告
        String csvReport = generateCsvReport(result);
        saveReportToFile(csvReport, new File(dir, baseName + ".csv").getAbsolutePath(), "CSV");
        
        // HTML报告
        String htmlReport = generateHtmlReport(result);
        saveReportToFile(htmlReport, new File(dir, baseName + ".html").getAbsolutePath(), "HTML");
    }
    
    /**
     * 转义CSV字段
     */
    private String escapeCsv(String field) {
        if (field == null) return "";
        if (field.contains(",") || field.contains("\"") || field.contains("\n")) {
            return "\"" + field.replace("\"", "\"\"") + "\"";
        }
        return field;
    }
    
    /**
     * 转义HTML字符
     */
    private String escapeHtml(String text) {
        if (text == null) return "";
        return text.replace("&", "&amp;")
                  .replace("<", "&lt;")
                  .replace(">", "&gt;")
                  .replace("\"", "&quot;")
                  .replace("'", "&#39;");
    }
}
